package com.joysuccess.minaserver.minaserver.raw;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.joysuccess.minaserver.utils.SocketUtil;
import org.apache.mina.core.buffer.IoBuffer;

import java.io.UnsupportedEncodingException;
import java.util.Map;


public class SocketMesaageManager {

    //包头长度（16byte）
    public static int HEAD_LEN = 16;

    //包头标记（4byte）
    public static byte[] HEAD_MARK = {0x11,0x11,0x11,0x11};
    public static int HEAD_MARK_LEN = 4;
    //协议版本（4byte）
    public static byte[] VERSION = {0x10,0x00,0x00,0x00};
    public static int VERSION_LEN = 4;
    //命令（4byte）
    public static int COMMAND_LEN = 4;
    //指令（1byte）
    public static int INS_LEN = 1;
    //指令类型（1byte）
    public static int INS_TYPE_LEN = 1;
    public static int COMMAND_RESERVED_LEN=2;
    //包体长度(4byte)
    public static int BODYLEN_LEN = 4;

    /**
     * 根据包头获取包头标识
     *
     * @param head
     * @return
     */
    public static byte[] getHeadMark(byte[] head) {
        byte[] headMark = new byte[HEAD_MARK_LEN];
        System.arraycopy(head, 0, headMark, 0, HEAD_LEN);
        return headMark;
    }

    /**
     * 根据包头获取协议版本
     *
     * @param head
     * @return
     */
    public static byte[] getVersion(byte[] head) {
        byte[] version = new byte[VERSION_LEN];
        System.arraycopy(head, 0, version, 0, HEAD_LEN);
        return version;
    }

    /**
     * 根据包头获取命令
     *
     * @param head
     * @return
     */
    public static byte[] getCommand(byte[] head) {
        byte[] command = new byte[COMMAND_LEN];
        System.arraycopy(head, HEAD_MARK_LEN + VERSION_LEN, command, 0, COMMAND_LEN);
        return command;
    }



    /**
     * 根据命令字段获取指令
     * @param command
     * @return
     */
    public static String getIns(byte[] command){
        byte[] ins = new byte[INS_LEN];
        System.arraycopy(command, 0, ins, 0, INS_LEN);
        return SocketUtil.binary(ins,2);
    }

    /**
     * 根据命令字段获取指令类型
     * @param command
     * @return
     */
    public static String getInsType(byte[] command){
        byte[] insType = new byte[INS_TYPE_LEN];
        System.arraycopy(command, INS_LEN, insType, 0, INS_TYPE_LEN);
        return SocketUtil.binary(insType,2);
    }


    /**
     * 根据包头获取包体长度
     *
     * @param head
     * @return
     */
    public static int getBodyLen(byte[] head) {
        byte[] bodyLen = new byte[BODYLEN_LEN];
        System.arraycopy(head, HEAD_MARK_LEN + VERSION_LEN + COMMAND_LEN, bodyLen, 0, BODYLEN_LEN);
        return SocketUtil.byteArrayToInt(bodyLen);
    }

    /**
     * 解析包体byte[]得到包体Json字符串
     *
     * @param body
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String getBodyStr(byte[] body) throws UnsupportedEncodingException {
        return new String(body, "GB2312");
    }

    /**
     * 告警包体解析
     *
     * @param alarmBody
     * @return
     */
    public static Map<String,String> getAlarm(String alarmBody) {
        return (Map) JSON.parse(alarmBody);
    }

    /**
     * 发送包封装
     * @param object 内容
     * @param type 类型
     * @return
     * @throws UnsupportedEncodingException
     */
    public static IoBuffer getSend(Object object, String type) throws UnsupportedEncodingException {
        byte[] body = JSONArray.toJSONString(object).getBytes("GB2312");
        byte[] bodyLen = SocketUtil.intToByteArray(body.length);

        IoBuffer buffer = IoBuffer.allocate(1024);
        buffer.setAutoExpand(true);

        //包头标记
        buffer.put(SocketMesaageManager.HEAD_MARK);
        //协议版本
        buffer.put(SocketMesaageManager.VERSION);
        //命令
        if (Ins.DATA.getValue() == type) {
            buffer.put(new byte[]{1, 0, 0, 0});
        } else if (Ins.ALARM.getValue() == type) {
            buffer.put(new byte[]{2, 0, 0, 0});
        }
        //包长
        buffer.put(bodyLen);
        //包体
        buffer.put(body);
        buffer.flip();
        return buffer;
    }

    public static void main(String[] args) {
//        List<CollectedData> list = new ArrayList<>();
//        CollectedData collectedData = new CollectedData();
//        collectedData.setPointDate(new Date().getTime());
//        collectedData.setPointOrigin("SNMP");
//        collectedData.setPointCode("a-b-c");
//        collectedData.setPointValue("100.0");
//        list.add(collectedData);
//        try {
//            String body = JSON.toJSONString(list);
//            IoBuffer buffer = getSend(body,"1");
//            byte[] result = ioBufferToByte(buffer);
//            String ss= bytesToHexFun3(result);
//            String s = ioBufferToString1(buffer);
//            System.out.println(buffer);
//        } catch (UnsupportedEncodingException e) {
//            e.printStackTrace();
//        }
    }

    public static String bytesToHexFun3(byte[] bytes) {
        StringBuilder buf = new StringBuilder(bytes.length * 2);
        for(byte b : bytes) { // 使用String的format方法进行转换
            buf.append(String.format("%02x", new Integer(b & 0xff)));
        }

        return buf.toString();
    }


    public static String ioBufferToString1(IoBuffer iobuffer){
        System.out.println("message = " + iobuffer + iobuffer.limit());
        iobuffer.flip();    //调换buffer当前位置，并将当前位置设置成0
        byte[] b = new byte[iobuffer.limit()];
        iobuffer.get(b);
        //此处用stringbuffer是因为　String类是字符串常量，是不可更改的常量。而StringBuffer是字符串变量，它的对象是可以扩充和修改的。
        StringBuffer stringBuffer = new StringBuffer();

        for(int i = 0; i < b.length; i++){
            System.out.println("====" + b[i]);
            stringBuffer.append((char) b[i]); //可以根据需要自己改变类型
            System.out.println(b[i] +"---------" +i);
        }
        return stringBuffer.toString();
    }

    public static byte [] ioBufferToByte(Object message)
    {
        if (!(message instanceof IoBuffer))
        {
            return null;
        }
        IoBuffer ioBuffer = (IoBuffer)message;
        byte[] b = new byte[ioBuffer.limit()];
        ioBuffer.get(b);
        return b;
    }
}
